home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Src / MTAconsole / assoc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  26.8 KB  |  1,228 lines

  1. /* routines to start and stop associations */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Src/MTAconsole/RCS/assoc.c,v 6.0 1991/12/18 20:26:48 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Src/MTAconsole/RCS/assoc.c,v 6.0 1991/12/18 20:26:48 jpo Rel $
  9.  *
  10.  * $Log: assoc.c,v $
  11.  * Revision 6.0  1991/12/18  20:26:48  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "util.h"
  19. #include <varargs.h>
  20. #include "console.h"
  21. #include "Qmgr-ops.h"
  22. #include "qmgr.h"
  23.  
  24. static char *myservice =     "pp qmgr";
  25. extern char *myname;
  26. int                remoteStop();
  27. static void            initiate_responder();
  28. static IFP            startfnx;
  29. static IFP            stopfnx;
  30. int                sd = -1;
  31. static int            tryForAuth;
  32. static struct client_dispatch   *channelread_op,
  33.                 *channelcontrol_op,
  34.                 *mtaread_op,
  35.                 *mtacontrol_op,
  36.                 *readchannelmtamessage_op,
  37.                 *msgcontrol_op,
  38.                 *quecontrol_op,
  39.                 *qmgrStatus_op,
  40.                 *quit_op;
  41. extern caddr_t retryMask;
  42. extern Authentication  authentication;
  43. extern char    *Qinformation, *Qversion;
  44. extern Widget    qversion;
  45. extern int    compat;
  46.  
  47. /* CLIENT OPERATIONS */
  48. extern int do_channelread();
  49. extern int do_channelcontrol();
  50. extern int do_mtaread();
  51. extern int do_mtacontrol();
  52. extern int do_readchannelmtamessage();
  53. extern int do_msgcontrol();
  54. extern int do_quecontrol();
  55. int do_quit();
  56.  
  57. /* CLIENT RESULTS */
  58. extern int channelread_result();
  59. extern int channelcontrol_result();
  60. extern int mtaread_result();
  61. extern int mtacontrol_result();
  62. extern int readchannelmtamessage_result();
  63. extern int msgcontrol_result();
  64. extern int quecontrol_result();
  65. extern int qmgrStatus_result();
  66.  
  67. /* CLIENT ERRORS */
  68. static int general_error();
  69.  
  70. #define channelread_error    general_error
  71. #define channelcontrol_error    general_error
  72. #define mtaread_error        general_error
  73. #define mtacontrol_error    general_error
  74. #define readchannelmtamessage_error    general_error
  75. #define msgcontrol_error    general_error
  76. #define quecontrol_error    general_error
  77. #define qmgrStatus_error    general_error
  78.  
  79. /* CLIENT STRUCTURE */
  80.  
  81. struct client_dispatch client_dispatches[] = {
  82. {
  83.     "channelread", operation_Qmgr_channelread,
  84. #ifdef PEPSY_VERSION
  85.     do_channelread, &_ZUNIV_mod, _ZUTCTimeUNIV,
  86. #else
  87.     do_channelread, free_UNIV_UTCTime,
  88. #endif
  89.     channelread_result, channelread_error,
  90.     "read information on channels"
  91. },
  92. {
  93.     "channelcontrol", operation_Qmgr_channelcontrol,
  94. #ifdef PEPSY_VERSION
  95.     do_channelcontrol, &_ZQmgr_mod, _ZChannelControlQmgr,
  96. #else
  97.     do_channelcontrol, free_Qmgr_ChannelControl,
  98. #endif
  99.     channelcontrol_result, channelcontrol_error,
  100.     "control channel"
  101. },
  102. {
  103.     "mtaread", operation_Qmgr_mtaread,
  104. #ifdef PEPSY_VERSION
  105.     do_mtaread, &_ZQmgr_mod, _ZMtaReadQmgr,
  106. #else
  107.     do_mtaread, free_Qmgr_MtaRead,
  108. #endif
  109.     mtaread_result, mtaread_error,
  110.     "read information on mtas"
  111. },
  112. {
  113.     "mtacontrol", operation_Qmgr_mtacontrol,
  114. #ifdef PEPSY_VERSION
  115.     do_mtacontrol, &_ZQmgr_mod, _ZMtaControlQmgr,
  116. #else
  117.     do_mtacontrol, free_Qmgr_MtaControl,
  118. #endif
  119.     mtacontrol_result, mtacontrol_error,
  120.     "control mta"
  121. },
  122. {
  123.     "readchannelmtamessage", operation_Qmgr_readChannelMtaMessage,
  124. #ifdef PEPSY_VERSION
  125.     do_readchannelmtamessage, &_ZQmgr_mod, _ZMsgReadQmgr,
  126. #else
  127.     do_readchannelmtamessage, free_Qmgr_MsgRead,
  128. #endif
  129.     readchannelmtamessage_result, readchannelmtamessage_error,
  130.     "read a set of messages"
  131. },
  132. {
  133.     "msgcontrol", operation_Qmgr_msgcontrol,
  134. #ifdef PEPSY_VERSION
  135.     do_msgcontrol, &_ZQmgr_mod, _ZMsgControlQmgr,
  136. #else
  137.     do_msgcontrol, free_Qmgr_MsgControl,
  138. #endif
  139.     msgcontrol_result, msgcontrol_error,
  140.     "control msg"
  141. },
  142. {
  143.     "quecontrol", operation_Qmgr_qmgrControl,
  144. #ifdef PEPSY_VERSION
  145.     do_quecontrol, &_ZQmgr_mod, _ZQMGRControlQmgr,
  146. #else
  147.     do_quecontrol, free_Qmgr_QMGRControl,
  148. #endif
  149.     quecontrol_result, quecontrol_error,
  150.     "control qmgr"
  151. },
  152. {
  153.     "qmgrStatus", operation_Qmgr_qmgrStatus, NULLIFP,
  154. #ifdef PEPSY_VERSION
  155.     &_ZQmgr_mod, _ZQmgrStatusQmgr,
  156. #else
  157.     free_Qmgr_QmgrStatus,
  158. #endif
  159.     qmgrStatus_result, qmgrStatus_error,
  160.     "control qmgr"
  161. },
  162. {
  163.     "quit",     0,      do_quit,
  164. #ifdef PEPSY_VERSION
  165.     NULL, 0, NULLIFP, NULLIFP,
  166. #else
  167.     NULLIFP, NULLIFP, NULLIFP,
  168. #endif
  169.     "terminate the association and exit"
  170. },
  171. {
  172.     NULL
  173. }
  174. };
  175.  
  176. /* SERVER OPERATIONS */
  177. extern int op_channelread();
  178. extern int op_mtaread();
  179. extern int op_readchannelmtamessage();
  180.  
  181. /* SERVER STRUCTURE */
  182. static struct server_dispatch server_dispatches[] = {
  183.     "channelread",      operation_Qmgr_channelread,     op_channelread,
  184.     "mtaread",          operation_Qmgr_mtaread,         op_mtaread,
  185.     "readchannelmtamessage", operation_Qmgr_readChannelMtaMessage,        op_readchannelmtamessage,
  186.     NULL
  187.     };
  188.  
  189. static void     acs_advise(),
  190.         ros_advise();
  191. void        advise();
  192. int    remoteStop();
  193. PE    passwdpeps[1], *passwdpep = passwdpeps;
  194. int     fatal;
  195.  
  196. initiate_assoc(argc, argv)
  197. int    argc;
  198. char    **argv;
  199. {
  200.     struct client_dispatch         *ix;
  201.  
  202.     initiate_responder(argc,argv, PLocalHostName(), myservice, 
  203.                server_dispatches,
  204.                table_Qmgr_Operations, NULLIFP, remoteStop);
  205.     
  206.     for (ix = client_dispatches; ix->ds_name; ix++){
  207.         if (strcmp(ix -> ds_name, "channelread") == 0)
  208.             channelread_op = ix;
  209.         else if (strcmp(ix->ds_name, "channelcontrol") == 0)
  210.             channelcontrol_op = ix;
  211.         else if (strcmp(ix->ds_name, "quit") == 0)
  212.             quit_op = ix;
  213.         else if (strcmp(ix->ds_name, "mtaread") == 0)
  214.             mtaread_op = ix;
  215.         else if (strcmp(ix->ds_name, "mtacontrol") == 0)
  216.             mtacontrol_op = ix;
  217.         else if (strcmp(ix->ds_name, "readchannelmtamessage") == 0)
  218.             readchannelmtamessage_op = ix;
  219.         else if (strcmp(ix->ds_name, "msgcontrol") == 0)
  220.             msgcontrol_op = ix;
  221.         else if (strcmp(ix->ds_name, "quecontrol") == 0)
  222.             quecontrol_op = ix;
  223.         else if (strcmp(ix->ds_name, "qmgrStatus") == 0)
  224.             qmgrStatus_op = ix;
  225.     }
  226. }
  227.  
  228. /* ARGSUSED */
  229. static void initiate_responder(argc, argv, host, service, dispatches, ops, start, stop)
  230. int            argc;
  231. char            **argv,
  232.             *host,
  233.             *service;
  234. struct server_dispatch     *dispatches;
  235. struct RyOperation     *ops;
  236. IFP            start,
  237.             stop;
  238. {
  239.     register struct server_dispatch    *ds;
  240.     struct RoSAPindication      rois;
  241.     register struct RoSAPindication    *roi = &rois;
  242.     register struct RoSAPpreject       *rop = &roi -> roi_preject;
  243.     
  244.     for (ds = dispatches; ds -> ds_name; ds++)
  245.         if (RyDispatch (NOTOK, ops, ds -> ds_operation, ds -> ds_vector, roi)
  246.             == NOTOK) {
  247.             ros_advise (rop, ds -> ds_name);
  248.             exit(1);
  249.         }
  250.  
  251.     startfnx = start;
  252.     stopfnx = stop;
  253. }
  254.  
  255. /*   */
  256. /* connection stuff */
  257.  
  258. /* ARGSUSED */
  259. int    assoc_start (argc, argv, service)
  260. int            argc;
  261. char            **argv,
  262.                 *service;
  263. /*struct RyOperation     ops[];
  264. struct client_dispatch    *dispatches;*/
  265. {
  266.     struct SSAPref             sfs;
  267.     register struct SSAPref     *sf;
  268.     register struct PSAPaddr     *pa;
  269.     struct AcSAPconnect         accs;
  270.     register struct AcSAPconnect       *acc = &accs;
  271.     struct AcSAPindication      acis;
  272.     register struct AcSAPindication    *aci = &acis;
  273.     register struct AcSAPabort     *aca = &aci -> aci_abort;
  274.     AEI                    aei;
  275.     OID                    ctx,
  276.                     tmppci;
  277.     struct PSAPctxlist         pcs;
  278.     register struct PSAPctxlist     *pc = &pcs;
  279.     struct RoSAPindication         rois;
  280.     register struct RoSAPindication    *roi = &rois;
  281.     register struct RoSAPpreject     *rop = &roi -> roi_preject;
  282.     int                result;
  283.  
  284.     if ((pa = str2paddr (argv[1])) == NULLPA) {
  285.         if ((aei = _str2aei (argv[1], service, QMGR_CTX_OID, 
  286.                      0, dap_user, dap_passwd)) == NULLAEI) {
  287.             fatal = TRUE;
  288.             advise (NULLCP, "%s: unknown entity",
  289.                 argv[1]);
  290.             return NOTOK;
  291.         }
  292.         if ((pa = aei2addr (aei)) == NULLPA) {
  293.             fatal = TRUE;
  294.             advise (NULLCP, "%s", "address translation failed");
  295.             return NOTOK;
  296.         }
  297.     }
  298.     if ((ctx = oid_cpy (QMGR_AC)) == NULLOID) {
  299.         fatal = TRUE;
  300.         advise (NULLCP, "%s", "out of memory");
  301.         return NOTOK;
  302.     }
  303.  
  304.     if ((tmppci = oid_cpy (QMGR_PCI)) == NULLOID) {
  305.         fatal = TRUE;
  306.         advise (NULLCP, "%s", "out of memory"); 
  307.         return NOTOK;
  308.     }
  309.     pc -> pc_nctx = 1;
  310.     pc -> pc_ctx[0].pc_id = 1;
  311.     pc -> pc_ctx[0].pc_asn = tmppci;
  312.     pc -> pc_ctx[0].pc_atn = NULLOID;
  313.  
  314.     if ((sf = addr2ref (PLocalHostName ())) == NULL) {
  315.         sf = &sfs;
  316.         (void) bzero ((char *) sf, sizeof *sf);
  317.     }
  318.  
  319.     switch (result = AcAsynAssocRequest (ctx, NULLAEI, NULLAEI, NULLPA,
  320.                          pa, pc, NULLOID, 0, ROS_MYREQUIRE,
  321.                          SERIAL_NONE, 0, sf, passwdpep, 1,
  322.                          NULLQOS, acc, aci, 1)) {
  323.         case NOTOK:
  324.         acs_advise (aca, "A-ASSOCIATE.REQUEST");
  325.         return NOTOK;
  326. #ifdef CONNECTING_1
  327.         case CONNECTING_1:
  328.         case CONNECTING_2:
  329.         sd = acc -> acc_sd;
  330.         ACCFREE (acc);
  331.         PP_TRACE (("Association initiated"));
  332.         return result;
  333. #else
  334.         case OK:
  335.         sd = acc -> acc_sd;
  336.         ACCFREE (acc);
  337.         PP_TRACE (("Association initiated"));
  338.         return OK;
  339. #endif
  340.         case DONE:
  341.         if (acc -> acc_result != ACS_ACCEPT) {
  342.             set_failmode (acc);
  343.             ACCFREE (acc);
  344.             return NOTOK;
  345.         }
  346.         sd = acc -> acc_sd;
  347.         
  348.         set_authmode(acc);
  349.  
  350.         ACCFREE (acc);
  351.  
  352.         if (RoSetService (sd, RoPService, roi) == NOTOK) {
  353.             ros_advise (rop, "set RO/PS fails");
  354.             return NOTOK;
  355.         }
  356.         PP_TRACE (("Service set"));
  357.         return DONE;
  358.         default:
  359.         advise (NULLCP, "%s", "Bad response from AcAsynAssocRequest");
  360.         return NOTOK;
  361.     }
  362. }
  363.  
  364. set_failmode (acc)
  365. struct AcSAPconnect       *acc;
  366. {
  367.     struct type_Qmgr_BindError    *be;
  368.     char                *info = NULLCP;
  369.     be = NULL;
  370.     
  371.     /* failed by qmgr so no point in retrying connect */
  372.     if (acc -> acc_result == ACS_PERMANENT)
  373.         fatal = TRUE;
  374.     
  375.     if (acc->acc_ninfo >= 1) {
  376.         if (decode_Qmgr_BindError (acc->acc_info[0], 1,
  377.                         NULLVP, NULLIP, &be) == NOTOK) 
  378.             PP_LOG(LLOG_EXCEPTIONS, ("failed to parse connect data [%s]",
  379.                          PY_pepy));
  380.         else {
  381.             if (be -> information != NULL) 
  382.                 info = qb2str (be -> information);
  383.  
  384.             advise (NULLCP,
  385.                 "Association rejected [%s] (%s)",
  386.                 (be -> reason == int_Qmgr_reason_badCredentials) ? "Bad Credentials" : "Congested",
  387.                 (info != NULLCP) ? info : "");
  388.             if (info != NULLCP) free(info);
  389.         }
  390.     } else 
  391.         advise (NULLCP,
  392.             "Association rejected: [%s]",
  393.             AcErrString (acc -> acc_result));
  394.         
  395. }
  396.  
  397. set_authmode (acc)
  398. struct AcSAPconnect       *acc;
  399. {
  400.     struct type_Qmgr_BindResult    *br;
  401.     
  402.     br = NULL;
  403.     authentication = limited;
  404.     if (Qversion != NULLCP) {
  405.         free(Qversion);
  406.         Qversion = NULLCP;
  407.     }
  408.     if (Qinformation != NULLCP) {
  409.         free (Qinformation);
  410.         Qinformation = NULLCP;
  411.     }
  412.  
  413.     if (acc->acc_ninfo >= 1) {
  414.         if (decode_Qmgr_BindResult (acc->acc_info[0], 1,
  415.                         NULLVP, NULLIP, &br) == NOTOK) 
  416.             PP_LOG(LLOG_EXCEPTIONS, ("failed to parse connect data [%s]",
  417.                          PY_pepy));
  418.         else {
  419.             switch (br->result) {
  420.                 case int_Qmgr_result_acceptedFullAccess:
  421.                 authentication = full;
  422.                 break;
  423.                 case int_Qmgr_result_acceptedLimitedAccess:
  424.                 default:
  425.                 authentication = limited;
  426.                 break;
  427.             }
  428.             if (br -> information != NULL) 
  429.                 Qinformation = qb2str (br -> information);
  430.  
  431.             if (br -> version != NULL) {
  432.                 Qversion = qb2str (br -> version);
  433.                 XtVaSetValues (qversion,
  434.                        XtNlabel, Qversion,
  435.                        NULL);
  436.                 free(Qversion);
  437.                 Qversion = NULLCP;
  438.             }
  439.  
  440.             free_Qmgr_BindResult(br);
  441.         }
  442.     }
  443. }
  444.  
  445. int acsap_retry (fd)
  446. int    fd;
  447. {
  448.     struct AcSAPconnect accs;
  449.     register struct AcSAPconnect   *acc = &accs;
  450.     struct AcSAPindication  acis;
  451.     register struct AcSAPindication *aci = &acis;
  452.     register struct AcSAPabort *aca = &aci -> aci_abort;
  453.     struct RoSAPindication rois;
  454.     register struct RoSAPindication *roi = &rois;
  455.     register struct RoSAPpreject *rop = &roi -> roi_preject;
  456.     int    result;
  457.  
  458.     PP_TRACE (("acsap_retry(%d)", fd));
  459.     switch (result = AcAsynRetryRequest (fd, acc, aci)) {
  460. #ifdef CONNECTING_1
  461.         case CONNECTING_1:
  462.         case CONNECTING_2:
  463.         ACCFREE (acc);
  464.         return result;
  465. #else
  466.         case OK:
  467.         ACCFREE (acc);
  468.         return OK;
  469. #endif
  470.         case NOTOK:
  471.         acs_advise (aca, "A-ASSOCIATE.REQUEST");
  472.         return NOTOK;
  473.         case DONE:
  474.         if (acc -> acc_result != ACS_ACCEPT) {
  475.             set_failmode(acc);
  476.             ACCFREE (acc);
  477.             return NOTOK;
  478.         }
  479.         sd = acc -> acc_sd;
  480.  
  481.         set_authmode(acc);
  482.  
  483.         ACCFREE (acc);
  484.         if (RoSetService (sd, RoPService, roi) == NOTOK) {
  485.             ros_advise (rop, "set RO/PS fails");
  486.             return NOTOK;
  487.         }
  488.         return DONE;
  489.         default:
  490.         advise (NULLCP, "%s", "Bad response from AcAsynRetryRequest");
  491.         return NOTOK;
  492.     }
  493. }
  494.  
  495. int  assoc_release (ad)
  496. int     ad;
  497. {
  498.     struct AcSAPrelease acrs;
  499.     register struct AcSAPrelease   *acr = &acrs;
  500.     struct AcSAPindication  acis;
  501.     register struct AcSAPindication *aci = &acis;
  502.     register struct AcSAPabort *aca = &aci -> aci_abort;
  503.  
  504. #ifdef    CONNECTING_1
  505.     if (AcRelRequest (ad, ACF_NORMAL, NULLPEP, 0, NOTOK, acr, aci) == NOTOK) {
  506. #else
  507.     if (AcRelRequest (ad, ACF_NORMAL, NULLPEP, 0, acr, aci) == NOTOK) {
  508. #endif
  509.         acs_advise (aca, "A-RELEASE.REQUEST");
  510.         return DONE;
  511.     }
  512.  
  513.     if (!acr -> acr_affirmative) {
  514.         (void) AcUAbortRequest (ad, NULLPEP, 0, aci);
  515.         advise (NULLCP, "Release rejected by peer: %d",
  516.             acr -> acr_reason);
  517.     }
  518.  
  519.     ACRFREE (acr);
  520.     PP_TRACE (("Association released"));
  521.  
  522.     return DONE;
  523. }
  524.  
  525. /*   */
  526. /* work routines */
  527. extern State    connectState;        
  528. static jmp_buf    toplevel;
  529.  
  530. static    int invoke (ad, ops, ds, args)
  531. int                ad;
  532. struct RyOperation         ops[];
  533. register struct client_dispatch    *ds;
  534. char                  **args;
  535. {
  536.     int                        result;
  537.     caddr_t                 in;
  538.     struct AcSAPindication  acis;
  539.     struct RoSAPindication  rois;
  540.     register struct RoSAPindication    *roi = &rois;
  541.     register struct RoSAPpreject       *rop = &roi -> roi_preject;
  542.  
  543.     in = NULL;
  544.  
  545.     if (ds -> ds_argument && (*ds -> ds_argument) (ad, ds, args, &in) == NOTOK)
  546.         return 0;
  547.  
  548.     switch (setjmp (toplevel)) {
  549.     case OK: 
  550.         break;
  551.  
  552.     default: 
  553.         if (stopfnx)
  554.         return (*stopfnx) (ad, (struct AcSAPfinish *) 0);
  555.         break;
  556.     case DONE:
  557.         (void) AcUAbortRequest (ad, NULLPEP, 0, &acis);
  558.         (void) RyLose (ad, roi);
  559.         return NOTOK;
  560.     }
  561.  
  562.     if (connectState != connected)
  563.         return NOTOK;
  564.  
  565.     switch (result = RyStub (ad, ops, ds -> ds_operation, RyGenID (ad),
  566.                  NULLIP, in, ds -> ds_result, 
  567.                  ds -> ds_error, ROS_SYNC, roi)) {
  568.     case NOTOK:        /* failure */
  569.         if (ROS_FATAL(rop->rop_reason)) {
  570.             ros_advise (rop, "STUB");
  571.             emergency_disconnect(ad);
  572.         }
  573.         break;
  574.         
  575.     case OK:        /* got a result/error response */
  576.         break;
  577.         
  578.     case DONE:        /* got RO-END? */
  579.         advise (NULLCP, "%s", "got RO-END.INDICATION");
  580.         connectState = notconnected;
  581.         /* NOTREACHED */
  582.  
  583.     default:
  584.         advise (NULLCP, "unknown return from RyStub=%d", result);
  585.         /* NOTREACHED */
  586.     }
  587.  
  588. #ifdef PEPSY_VERSION
  589.     if (ds -> ds_fr_mod && in)
  590.         fre_obj (in,  ds -> ds_fr_mod -> md_dtab[ds -> ds_fr_index],
  591.              ds -> ds_fr_mod);
  592. #else
  593.     if (ds -> ds_free && in)
  594.         (*ds -> ds_free)(in);
  595. #endif
  596.     return OK;
  597. }
  598.  
  599. extern Operations    currentop;
  600.  
  601. my_invoke(op, args)
  602. Operations    op;
  603. char        **args;
  604. {
  605.     currentop = op;
  606.     StartWait();
  607.     switch (op) {
  608.         case chanread:
  609.         invoke(sd, table_Qmgr_Operations, 
  610.                channelread_op,(char **) NULL);
  611.           update_time_label();
  612.         break;
  613.         case chanstop:
  614.         case chanstart:
  615.         case chanclear:
  616.         case chancacheadd:
  617.         invoke(sd, table_Qmgr_Operations,
  618.                channelcontrol_op, args);
  619.         break;
  620.         case mtaread:
  621.         invoke(sd, table_Qmgr_Operations,
  622.                mtaread_op, args);
  623.         break;
  624.         case mtastop:
  625.         case mtastart:
  626.         case mtaclear:
  627.         case mtacacheadd:
  628.         invoke(sd, table_Qmgr_Operations,
  629.                mtacontrol_op, args);
  630.         break;
  631.         case readchannelmtamessage:
  632.         invoke(sd, table_Qmgr_Operations,
  633.                readchannelmtamessage_op, args);
  634.         break;
  635.         case msgstop:
  636.         case msgstart:
  637.         case msgclear:
  638.         case msgcacheadd:
  639.         invoke(sd, table_Qmgr_Operations,
  640.                msgcontrol_op, args);
  641.         break;
  642.         case quit:
  643.         invoke(sd, table_Qmgr_Operations,
  644.                quit_op, (char **) NULL);
  645.         break;
  646.         case connect:
  647.         EndWait();
  648.         return do_connect(args);
  649.         case disconnect:
  650.         do_disconnect();
  651.         break;
  652.         case quecontrol:
  653.         invoke(sd, table_Qmgr_Operations,
  654.                quecontrol_op, args);
  655.         break;
  656.         case qmgrStatus:
  657.         invoke(sd, table_Qmgr_Operations,
  658.                qmgrStatus_op, args);
  659.         EndWait();
  660.         return 0;
  661.         default:
  662.         break;
  663.     }
  664.     InitRefreshTimeOut((unsigned long) 0);
  665.     EndWait();
  666.     return 0;
  667. }
  668.  
  669. /*   */
  670. /* advising routines */
  671.  
  672. static void    acs_advise (aca, event)
  673. register struct AcSAPabort *aca;
  674. char   *event;
  675. {
  676.     char    buffer[BUFSIZ];
  677.  
  678.     if (aca -> aca_cc > 0)
  679.         (void) sprintf (buffer, "[%s] %*.*s",
  680.                 AcErrString (aca -> aca_reason),
  681.                 aca -> aca_cc, aca -> aca_cc, aca -> aca_data);
  682.     else
  683.         (void) sprintf (buffer, "[%s]",
  684.                 AcErrString (aca -> aca_reason));
  685.  
  686.     advise (NULLCP, "%s: %s (source %d)", event, buffer,
  687.         aca -> aca_source);
  688. }
  689.  
  690. int  ros_work (fd)
  691. int     fd;
  692. {
  693.     int     result;
  694.     caddr_t out;
  695.     struct AcSAPindication  acis;
  696.     struct RoSAPindication  rois;
  697.     register struct RoSAPindication *roi = &rois;
  698.     register struct RoSAPpreject   *rop = &roi -> roi_preject;
  699.  
  700.     switch (setjmp (toplevel)) {
  701.     case OK: 
  702.         break;
  703.  
  704.     default: 
  705.         if (stopfnx)
  706.         return (*stopfnx) (fd, (struct AcSAPfinish *) 0);
  707.         break;
  708.     case DONE:
  709.         (void) AcUAbortRequest (fd, NULLPEP, 0, &acis);
  710.         (void) RyLose (fd, roi);
  711.         return NOTOK;
  712.     }
  713.  
  714.     switch (result = RyWait (fd, NULLIP, &out, OK, roi)) {
  715.     case NOTOK: 
  716.         if (rop -> rop_reason == ROS_TIMER)
  717.         break;
  718.     case OK: 
  719.     case DONE: 
  720.         ros_indication (fd, roi);
  721.         break;
  722.  
  723.     default: 
  724.         advise (NULLCP, "unknown return from RoWaitRequest=%d", result);
  725.     }
  726.     return OK;
  727. }
  728.  
  729. ros_indication (ad, roi)
  730. int     ad;
  731. register struct RoSAPindication *roi;
  732. {
  733.     int     reply,
  734.     result;
  735.  
  736.     switch (roi -> roi_type) {
  737.         case ROI_INVOKE: 
  738.         case ROI_RESULT: 
  739.         case ROI_ERROR: 
  740.         advise (NULLCP, "unexpected indication type=%d",
  741.                roi -> roi_type);
  742.         break;
  743.  
  744.         case ROI_UREJECT: 
  745.         {
  746.             register struct RoSAPureject   *rou =
  747.                 &roi -> roi_ureject;
  748.  
  749.             if (rou -> rou_noid)
  750.                 advise (NULLCP,
  751.                     "RO-REJECT-U.INDICATION/%d: %s",
  752.                     ad, RoErrString (rou -> rou_reason));
  753.             else
  754.                 advise (NULLCP,
  755.                     "RO-REJECT-U.INDICATION/%d: %s (id=%d)",
  756.                     ad, RoErrString (rou -> rou_reason),
  757.                     rou -> rou_id);
  758.         }
  759.         break;
  760.  
  761.         case ROI_PREJECT: 
  762.         {
  763.             register struct RoSAPpreject   *rop = &roi -> roi_preject;
  764.             connectState = notconnected;
  765.             if (ROS_FATAL (rop -> rop_reason)) {
  766.                 ros_adios (rop, "RO-REJECT-P.INDICATION");
  767.                 emergency_disconnect(ad);
  768.             }
  769.             ros_advise (rop, "RO-REJECT-P.INDICATION");
  770.         }
  771.         break;
  772.  
  773.         case ROI_FINISH: 
  774.         {
  775.             register struct AcSAPfinish *acf = &roi -> roi_finish;
  776.             struct AcSAPindication  acis;
  777.             register struct AcSAPabort *aca = &acis.aci_abort;
  778.  
  779.             advise (NULLCP, "A-RELEASE.INDICATION/%d: %d",
  780.                 ad, acf -> acf_reason);
  781.  
  782.             reply = stopfnx ? (*stopfnx) (ad, acf) : ACS_ACCEPT;
  783.  
  784.             result = AcRelResponse (ad, reply, ACR_NORMAL, NULLPEP, 0,
  785.                         &acis);
  786.  
  787.             ACFFREE (acf);
  788.  
  789.             if (result == NOTOK)
  790.                 acs_advise (aca, "A-RELEASE.RESPONSE");
  791.             else
  792.                 if (reply != ACS_ACCEPT)
  793.                     break;
  794.             longjmp (toplevel, DONE);
  795.         }
  796.         /* NOTREACHED */
  797.  
  798.         default: 
  799.         advise (NULLCP, "unknown indication type=%d", roi -> roi_type);
  800.     }
  801. }
  802.  
  803. ros_adios (rop, event)
  804. register struct RoSAPpreject *rop;
  805. char   *event;
  806. {
  807.     ros_advise (rop, event);
  808.  
  809.     longjmp (toplevel, NOTOK);
  810. }
  811.  
  812. static void    ros_advise (rop, event)
  813. register struct RoSAPpreject *rop;
  814. char   *event;
  815. {
  816.     char    buffer[BUFSIZ];
  817.  
  818.     if (rop -> rop_cc > 0)
  819.         (void) sprintf (buffer, "[%s] %*.*s",
  820.                 RoErrString (rop -> rop_reason),
  821.                 rop -> rop_cc, rop -> rop_cc, rop -> rop_data);
  822.     else
  823.         (void) sprintf (buffer, "[%s]",
  824.                 RoErrString (rop -> rop_reason));
  825.  
  826.     advise (NULLCP, "%s: %s", event, buffer);
  827. }
  828.  
  829. extern Widget    header,
  830.         error,
  831.         refresh_command;
  832. extern int    autoReconnect,
  833.         userConnected,
  834.         errorUp;
  835. extern char    *hostname;
  836.  
  837. #ifndef lint
  838. void advise (va_alist)
  839. va_dcl
  840. {
  841.     va_list ap;
  842.     
  843.     char    buffer[BUFSIZ],
  844.         headerbuf[BUFSIZ];
  845.  
  846.     va_start (ap);
  847.     asprintf (buffer, ap);
  848.     if (header != NULL) {
  849.         XtSetMappedWhenManaged(error, True);
  850.         errorUp = 5;
  851.     }
  852.     if (header == NULL)
  853.         printf("%s\n",buffer);
  854.     else if (connectState == notconnected && 
  855.          autoReconnect == TRUE
  856.          && fatal == FALSE) {
  857.         sprintf(headerbuf,"Attempting to reconnect to %s",
  858.             hostname);
  859.         XtVaSetValues(header,
  860.               XtNlabel, headerbuf,
  861.               NULL);
  862.         XtVaSetValues(error,
  863.               XtNlabel, buffer,
  864.               NULL);
  865.     } else {
  866.         XtVaSetValues(error,
  867.               XtNlabel, buffer,
  868.               NULL);
  869.     }
  870.     va_end (ap);
  871. }
  872. #else
  873. /* VARARGS2 */
  874.  
  875. void advise(what, fmt)
  876. char    *what,
  877.     *fmt;
  878. {
  879.     advise(what,fmt);
  880. }
  881. #endif
  882.  
  883. /*   */
  884. /* error routine */
  885.  
  886. /* ARGSUSED */
  887. static general_error (ad, id, err, parameter, roi)
  888. int     ad,
  889.     id,
  890.     err;
  891. caddr_t parameter;
  892. struct RoSAPindication *roi;
  893. {
  894.     register struct RyError *rye;
  895.  
  896.     if (err == RY_REJECT) {
  897.         advise (NULLCP, "%s", RoErrString ((int) parameter));
  898.         return OK;
  899.     }
  900.  
  901.     if ((rye = finderrbyerr (table_Qmgr_Errors, err)) != NULL)
  902.         advise (NULLCP, "Error: %s", rye -> rye_name);
  903.     else
  904.         advise (NULLCP, "Error: %d", err);
  905.  
  906.     return OK;
  907. }
  908.  
  909. /*   */
  910.  
  911. /* ARGSUSED */
  912. int remoteStop(fd, dummy)
  913. int    fd;
  914. struct AcSAPfinish    *dummy;
  915. {
  916.     struct AcSAPindication  acis;
  917.     struct RoSAPindication  rois;
  918.     register struct RoSAPindication *roi = &rois;
  919.  
  920.     /* x release */
  921.     connectState = notconnected;
  922.     
  923.     SensitizeButtons(False);
  924.     TermRefreshTimeOut();
  925.     TermConnectRetry();
  926.     TermListen();
  927.  
  928.     if (autoReconnect == FALSE)
  929.         userConnected = FALSE;
  930.     /* isode release */
  931.     (void) AcUAbortRequest (fd, NULLPEP, 0, &acis);
  932.     (void) RyLose (fd, roi);
  933.     
  934.     if (autoReconnect == TRUE && userConnected == TRUE) {
  935.         clear_displays();
  936.         XtVaSetValues(refresh_command,
  937.               XtNlabel, "Reconnect",
  938.               NULL);
  939.         InitConnectTimeOut();
  940.         MapVolume(False);
  941.     } else {
  942.         XtVaSetValues(header,
  943.               XtNlabel, NO_CONNECTION,
  944.               NULL);
  945.         ResetForDisconnect(); 
  946.     }
  947.     return NOTOK;
  948. }
  949.  
  950. /* ARGSUSED */
  951. emergency_disconnect(ad)
  952. int    ad;
  953. {
  954.     char    headerbuf[BUFSIZ];
  955.  
  956.     connectState = notconnected;
  957.     SensitizeButtons(False);
  958.     TermRefreshTimeOut();
  959.     TermConnectRetry();
  960.     TermListen();
  961.  
  962.     if (autoReconnect == FALSE)
  963.         userConnected = FALSE;
  964.     if (autoReconnect == TRUE && userConnected == TRUE) {
  965.         clear_displays();
  966.         XtVaSetValues(refresh_command,
  967.               XtNlabel, "Reconnect",
  968.               NULL);
  969.         sprintf(headerbuf,"Attempting to reconnect to %s",
  970.             hostname);
  971.         XtVaSetValues(header,
  972.               XtNlabel, headerbuf,
  973.               NULL);
  974.         InitConnectTimeOut();
  975.         MapVolume(False);
  976.     } else {
  977.         XtVaSetValues(header,
  978.               XtNlabel, NO_CONNECTION,
  979.               NULL);
  980.         ResetForDisconnect(); 
  981.     }
  982.  
  983. }
  984.  
  985. /*   */
  986.  
  987.  
  988. /* disconnect from current host with part of a quit */
  989. do_disconnect()
  990. {
  991.     struct AcSAPrelease acrs;
  992.     register struct AcSAPrelease   *acr = &acrs;
  993.     struct AcSAPindication  acis;
  994.     register struct AcSAPindication *aci = &acis;
  995.     register struct AcSAPabort *aca = &aci -> aci_abort;
  996.  
  997.     if (connectState == connected) {
  998.         /* Disconnect(sd) */
  999.         TermListen();
  1000.         connectState = notconnected;
  1001.  
  1002. #ifdef    CONNECTING_1
  1003.         if (AcRelRequest (sd, ACF_NORMAL, NULLPEP, 0, NOTOK, acr, aci) == NOTOK) {
  1004. #else
  1005.         if (AcRelRequest (sd, ACF_NORMAL, NULLPEP, 0, acr, aci) == NOTOK) {
  1006. #endif
  1007.             acs_advise (aca, "A-RELEASE.REQUEST");
  1008.             return;
  1009.         }
  1010.  
  1011.         if (!acr -> acr_affirmative) {
  1012.             (void) AcUAbortRequest (sd, NULLPEP, 0, aci);
  1013.             advise (NULLCP, "Release rejected by peer: %d", acr -> acr_reason);
  1014.         }
  1015.  
  1016.         ACRFREE (acr);
  1017.         sd = -1;
  1018.     } else if (autoReconnect == TRUE) {
  1019.         TermConnectTimeOut();
  1020.         XtVaSetValues(header,
  1021.               XtNlabel, NO_CONNECTION,
  1022.               NULL);
  1023.         autoReconnect = FALSE;
  1024.     }
  1025. }
  1026.  
  1027. /* ARGSUSED */
  1028. int  do_quit (ad, ds, args, arg)
  1029. int     ad;
  1030. struct client_dispatch *ds;
  1031. char      **args,
  1032.     **arg;
  1033. {
  1034.     struct AcSAPrelease acrs;
  1035.     register struct AcSAPrelease   *acr = &acrs;
  1036.     struct AcSAPindication  acis;
  1037.     register struct AcSAPindication *aci = &acis;
  1038.     register struct AcSAPabort *aca = &aci -> aci_abort;
  1039.  
  1040.     if (ad >= 0) {
  1041. #ifdef    CONNECTING_1
  1042.         if (AcRelRequest (ad, ACF_NORMAL, NULLPEP, 0, NOTOK, acr, aci) == NOTOK)
  1043. #else
  1044.         if (AcRelRequest (ad, ACF_NORMAL, NULLPEP, 0, acr, aci) == NOTOK)
  1045. #endif
  1046.             acs_advise (aca, "A-RELEASE.REQUEST");
  1047.  
  1048.         if (!acr -> acr_affirmative) {
  1049.             (void) AcUAbortRequest (ad, NULLPEP, 0, aci);
  1050.             advise (NULLCP, "Release rejected by peer: %d", acr -> acr_reason);
  1051.         }
  1052.         ad = -1;
  1053.     }
  1054.     terminate_display();
  1055.     exit (0);
  1056.  
  1057. }
  1058.  
  1059. /*   */
  1060.  
  1061. do_connect(phost)
  1062. char    **phost;
  1063. {
  1064.     char    *targv[2];
  1065.     int    result;
  1066.  
  1067.     targv[0] = myname;
  1068.     targv[1] = *phost;
  1069.     fatal = FALSE;
  1070.     switch(result = assoc_start(2, targv, myservice)) {
  1071. #ifdef    CONNECTING_1
  1072.         case CONNECTING_1:
  1073.         case CONNECTING_2:
  1074.         Connecting(result);
  1075.         break;
  1076. #else
  1077.         case OK:
  1078.         retryMask = (caddr_t) XtInputWriteMask;
  1079.         Connecting(result);
  1080.         break;
  1081. #endif
  1082.         case DONE:
  1083.         Connected();
  1084.         break;
  1085.         case NOTOK:
  1086.         default:
  1087.         NotConnected();
  1088.         break;
  1089.     }
  1090.     return result;
  1091. }
  1092.  
  1093. char    buf[BUFSIZ];
  1094. extern Widget    header,
  1095.         error,
  1096.         qcontrol_command,
  1097.         connect_command,
  1098.         refresh_command,
  1099.         statistics;
  1100. extern Mode    mode;
  1101.  
  1102. Connected()
  1103. {
  1104.     sprintf(buf, "Connected to %s (%s)",
  1105.         (Qinformation != NULLCP && *Qinformation != '\0') ? Qinformation : hostname,
  1106.         (authentication == full) ? "full authorisation" : "limited authorisation");
  1107.     XtVaSetValues(header,
  1108.           XtNlabel, buf,
  1109.           NULL);
  1110.     display_time_label();
  1111. /*    if (authentication != full && tryForAuth == TRUE)
  1112.         advise(NULLCP, "%s",
  1113.                "Failed to gain authorised connection");
  1114.     else
  1115.         XtSetMappedWhenManaged(error, False); */
  1116.     MapButtons(authentication == full);
  1117.     if (full == authentication 
  1118.         && monitor == mode)
  1119.         XtSetMappedWhenManaged (qcontrol_command, False);
  1120.     SensitizeButtons(True);
  1121.     XtVaSetValues(connect_command,
  1122.           XtNlabel, "disconnect",
  1123.           NULL);
  1124.     XtVaSetValues(refresh_command,
  1125.           XtNlabel, "refresh",
  1126.           NULL);
  1127.     XtSetMappedWhenManaged(error, False);
  1128.     errorUp = 0;
  1129.     connectState = connected;
  1130.     TaiInit();
  1131.     InitListen(sd);
  1132.     if (!compat)
  1133.         my_invoke(qmgrStatus, (char **) NULL);
  1134.     InitRefreshTimeOut((unsigned long) 500);
  1135.     TermConnectTimeOut();
  1136.     userConnected = TRUE;
  1137. }
  1138.  
  1139. extern Widget    time_label;
  1140.  
  1141. NotConnected()
  1142. {
  1143.     char    headerbuf[BUFSIZ];
  1144.     connectState = notconnected;    
  1145.     undisplay_time_label();
  1146.     TermRefreshTimeOut();
  1147.     MapButtons(False);
  1148.     MapVolume(False);
  1149.     if (autoReconnect == TRUE 
  1150.         && fatal == FALSE) {
  1151.         XtVaSetValues(refresh_command,
  1152.               XtNlabel, "reconnect",
  1153.               NULL);
  1154.         XtVaSetValues(connect_command,
  1155.               XtNlabel, "disconnect",
  1156.               NULL);
  1157.         sprintf(headerbuf, "Attempting to reconnect to %s",hostname);
  1158.         XtVaSetValues(header,
  1159.               XtNlabel, headerbuf,
  1160.               NULL);
  1161.         InitConnectTimeOut();
  1162.     } else {
  1163.         XtVaSetValues(header,
  1164.               XtNlabel, NO_CONNECTION,
  1165.               NULL);
  1166.         userConnected = FALSE;
  1167.         ResetForDisconnect();
  1168.     }
  1169.     
  1170. }
  1171.  
  1172. Connecting(res)
  1173. int    res;
  1174. {
  1175.     connectState = connecting;
  1176.     sprintf(buf,"Connecting to %s",hostname);
  1177.     XtVaSetValues(header,
  1178.           XtNlabel, buf,
  1179.           NULL);
  1180.     XtVaSetValues(connect_command,
  1181.           XtNlabel, "disconnect",
  1182.           NULL);
  1183.     InitConnectRetry(sd, res);
  1184. }
  1185.  
  1186. struct type_Qmgr_BindArgument    *ba;
  1187.  
  1188. fillin_passwdpep(user, passwd, auth)
  1189. char    *user,
  1190.     *passwd;
  1191. int    auth;
  1192. {
  1193.     
  1194.     if (*passwdpep != NULL) {
  1195.         pe_free(*passwdpep);
  1196.         free_Qmgr_BindArgument(ba);
  1197.         *passwdpep = NULL;
  1198.     }
  1199.  
  1200.     ba = (struct type_Qmgr_BindArgument *) smalloc (sizeof *ba);
  1201.     
  1202.     if (auth != TRUE) {
  1203.         /* no authentication */
  1204.         ba -> offset = type_Qmgr_BindArgument_noAuthentication;
  1205.         tryForAuth = FALSE;
  1206.     } else {
  1207.         ba -> offset = type_Qmgr_BindArgument_weakAuthentication;
  1208.         ba -> un.weakAuthentication = 
  1209.             (struct type_Qmgr_WeakAuthentication *) 
  1210.                 smalloc(sizeof(struct type_Qmgr_WeakAuthentication));
  1211.         ba -> un.weakAuthentication->username = str2qb(user, strlen(user), 1);
  1212.         if (passwd != NULLCP && *passwd != '\0')
  1213.             ba -> un.weakAuthentication->passwd = str2qb(passwd, strlen(passwd), 1);
  1214.         else 
  1215.             ba -> un.weakAuthentication->passwd = NULL;
  1216.         tryForAuth = TRUE;
  1217.     }
  1218.         
  1219.     if (encode_Qmgr_BindArgument(passwdpep, 1, NULLCP, 0, ba) == NOTOK) {
  1220.         PP_LOG(LLOG_EXCEPTIONS,
  1221.                ("failed to encode BindArgument [%s]", PY_pepy));
  1222.         *passwdpep = NULLPE;
  1223.         free_Qmgr_BindArgument(ba);
  1224.         exit(1);
  1225.     }
  1226.     (*passwdpep)->pe_context = 3;
  1227. }
  1228.